package pe.edu.upc.dew.bibliotecaweb.service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import pe.edu.upc.dew.bibliotecaweb.dao.EjemplarDao;
import pe.edu.upc.dew.bibliotecaweb.dao.PrestamoDao;
import pe.edu.upc.dew.bibliotecaweb.dao.ReservaDao;
import pe.edu.upc.dew.bibliotecaweb.model.Ejemplar;
import pe.edu.upc.dew.bibliotecaweb.model.Prestamo;
import pe.edu.upc.dew.bibliotecaweb.model.Reserva;

/**
 * Clase PrestamoService, contiene la lógica del negocio del préstamo.
 * @author DEW 2010
 */
public class PrestamoService {

    private PrestamoDao prestamoDao;
    private EjemplarDao ejemplarDao;
    private ReservaDao reservaDao;

    /**
     * Constructor de la clase PrestamoService
     */
    public PrestamoService() {
        this.prestamoDao = new PrestamoDao();
        this.ejemplarDao = new EjemplarDao();
        this.reservaDao = new ReservaDao();
    }

    /**
     * Método que registra ul préstamo de uin libto.
     * @param idEjemplar Identificador del ejemplar
     * @param idReserva Identificador de la reserva
     * @param fecha Fecha de ejecución de la reserva (cuando se realiza el préstamo).
     * @return Retorna true si se registra el préstamo correctamente sino retorna false
     */
    public boolean registraPrestamo(int idEjemplar, int idReserva, String fecha) {
        boolean valor = false;
        Prestamo prestamo = new Prestamo();

        Ejemplar ejemplar = new Ejemplar();
        ejemplar.setIdEjemplar(idEjemplar);

        Reserva reserva = new Reserva();
        reserva.setIdReserva(idReserva);

        prestamo.setReserva(reserva);
        prestamo.setEjemplar(ejemplar);
        prestamo.setFechaPrestamo(fecha);

        Calendar cal = Calendar.getInstance(Locale.ENGLISH);
        cal.add(Calendar.DAY_OF_MONTH, 5);
        prestamo.setFechaDevolucion(getDateTime(cal.getTime()));

        try {
            prestamoDao.generaPrestamo(prestamo);
            ejemplarDao.actualizaEstadoEjemplar(idEjemplar);
            reservaDao.actualizaEstadoReserva(idReserva);
            valor = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return valor;
    }

    /**
     * Método que busca el préstamo pendiente de devolución de un usuario.
     * @param usuario Nombre de usuario de la persona
     * @return Retorna un objeto de tipo Préstamo
     */
    public Prestamo buscaPrestamoUsuario(String usuario) {
        Prestamo prestamo = prestamoDao.getPrestamoPorUsuario(usuario);
        if (prestamo != null) {
            return prestamo;
        } else {
            return null;
        }
    }

    /**
     * Método que regisra la devolucion de de un libro.
     * @param idPrestamo Identificador del préstamo
     * @param fechaDevolucion Fecha en que se está registrando la devolución.
     * @param idEjemplar Identificador del ejemplar prestado
     * @return Retorna true si se registra la devolución en fecha. False si se hace fuera de fecha
     */
    public boolean registraDevolucion(int idPrestamo, String fechaDevolucion, Integer idEjemplar) {
        boolean valor = false;

        try {
            prestamoDao.registraDevolucion(idPrestamo);
            ejemplarDao.actualizaEstadoEjemplarDevolucion(idEjemplar);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (!stringToDate(fechaDevolucion).before(Calendar.getInstance().getTime())) {
            valor = true;
        }
        return valor;
    }

    /**
     * Método que permite convertir una cadena  a objeto tipo fecha
     * @param fecha objeto de tipo cadena
     * @return Retorna un objeto del tipo date con el formato "yyyy-MM-dd"
     */
    private Date stringToDate(String fecha) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = dateFormat.parse(fecha);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * Método que permite darle el formato "yyyy-MM-dd" a la fecha recibida
     * @param fecha objeto de tipo Date
     * @return Retorna una cadena que contiene una fecha en el formato "yyyy-MM-dd"
     */
    private String getDateTime(Date fecha) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(fecha);
    }
}
